const MenuModel = require('../models/menuModel');
const appError = require('../utils/appError');
const { listToTree } = require('../utils/utils');

class MenuService {
  // 检查菜单名是否已存在
  async isNameExist (name) {
    const menu = await MenuModel.findOne({ name });
    return !!menu;
  }

  // 创建菜单
  async create(data, created_by) {
    // 验证必填字段
    if (!data.name || !data.code) {
      appError(400, '菜单名和菜单码都是必填项', {
        name: !data.name ? '菜单名是必填项' : null,
        code: !data.code ? '菜单码是必填项' : null
      });
    }

    // 检查菜单名是否存在
    const exists = await this.isNameExist(data.name);
    if (exists) {
      appError(409, '菜单名已存在');
    }

    // 创建新菜单
    const newMenu = new MenuModel({ ...data, created_by });
    await newMenu.save();
    return newMenu;
  }

  // 更新菜单
  async update(data, updated_by) {
    const menu_id = data.id
    const menu = await MenuModel.findOne({ menu_id });
    if (!menu) {
      appError(400, '菜单不存在');
    }
    await MenuModel.updateOne({ menu_id }, { $set: { ...data, updated_by } });
    return await MenuModel.findOne({ menu_id });
  }

  // 删除菜单
  async delete(menu_id) {
    const menu = await MenuModel.findOne({ menu_id });
    if (!menu) {
      appError(400, '菜单不存在');
    }
    await MenuModel.deleteOne({ menu_id });
  }

  // 获取单个菜单
  async findOne(menu_id) {
    return await MenuModel.findOne({ menu_id });
  }

  // 获取所有菜单
  async findAll(type) {
    const menus = await MenuModel.find();
    menus.sort((a, b) => a.sort_order - b.sort_order)
    const data = menus.map(menu => {
      return {
        menu_id: menu.menu_id,
        name: menu.name,
        code: menu.code,
        path: menu.path,
        description: menu.description,
        parent_id: menu.parent_id,
        level: menu.level,
        sort_order: menu.sort_order,
        icon: menu.icon,
        is_visible: menu.is_visible,
        created_at: menu.created_at,
        updated_at: menu.updated_at,
        created_by: menu.created_by,
        updated_by: menu.updated_by
      }
    })

    if (type !== 'tree') {
      return data;
    }

    return listToTree(data, 'parent_id', 'menu_id')
  }
}

module.exports = new MenuService();